package com.example.backend.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.example.backend.config.OssConfig;
import com.example.backend.service.OssService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * OSS服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OssServiceImpl implements OssService {
    
    private final OSS ossClient;
    private final OssConfig ossConfig;
    
    @Override
    public String upload(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        try {
            return upload(file.getInputStream(), originalFilename);
        } catch (IOException e) {
            log.error("文件上传失败", e);
            throw new RuntimeException("文件上传失败", e);
        }
    }
    
    @Override
    public String upload(InputStream inputStream, String fileName) {
        // 生成文件路径
        String filePath = generateFilePath(fileName);
        
        try {
            // 创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType(getContentType(fileName));
            
            // 上传文件
            ossClient.putObject(ossConfig.getBucketName(), filePath, inputStream, metadata);
            
            return filePath;
        } catch (Exception e) {
            log.error("文件上传失败", e);
            throw new RuntimeException("文件上传失败", e);
        }
    }
    
    @Override
    public void delete(String fileUrl) {
        try {
            ossClient.deleteObject(ossConfig.getBucketName(), fileUrl);
        } catch (Exception e) {
            log.error("文件删除失败", e);
            throw new RuntimeException("文件删除失败", e);
        }
    }
    
    @Override
    public InputStream download(String fileUrl) {
        try {
            OSSObject object = ossClient.getObject(ossConfig.getBucketName(), fileUrl);
            return object.getObjectContent();
        } catch (Exception e) {
            log.error("文件下载失败", e);
            throw new RuntimeException("文件下载失败", e);
        }
    }
    
    @Override
    public String getFileUrl(String fileUrl) {
        return String.format("https://%s.%s/%s", 
                ossConfig.getBucketName(), 
                ossConfig.getEndpoint(), 
                fileUrl);
    }
    
    /**
     * 生成文件路径
     */
    private String generateFilePath(String fileName) {
        // 生成日期路径
        LocalDateTime now = LocalDateTime.now();
        String datePath = now.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        
        // 生成UUID文件名
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        
        // 获取文件扩展名
        String extension = "";
        if (fileName.contains(".")) {
            extension = fileName.substring(fileName.lastIndexOf("."));
        }
        
        // 返回完整路径
        return String.format("upload/%s/%s%s", datePath, uuid, extension);
    }
    
    /**
     * 获取文件ContentType
     */
    private String getContentType(String fileName) {
        // 文件的后缀名
        String extension = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
        
        // 根据后缀名判断ContentType
        switch (extension) {
            case ".jpg":
            case ".jpeg":
                return "image/jpeg";
            case ".png":
                return "image/png";
            case ".gif":
                return "image/gif";
            case ".pdf":
                return "application/pdf";
            case ".doc":
                return "application/msword";
            case ".docx":
                return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
            case ".xls":
                return "application/vnd.ms-excel";
            case ".xlsx":
                return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            default:
                return "application/octet-stream";
        }
    }
} 